package com.finance.rule.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.finance.base.constant.BaseConstants;
import com.finance.base.enums.*;
import com.finance.base.exception.BaseException;
import com.finance.framework.controller.BaseController;
import com.finance.framework.controller.Result;
import com.finance.framework.file.FileUtils;
import com.finance.framework.lang.BeanUtils;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.rule.bean.pojo.PieceRangeList;
import com.finance.rule.bean.pojo.PieceRangeRule;
import com.finance.rule.export.PieceParse;
import com.finance.rule.export.PieceParseBean;
import com.finance.rule.request.PieceRangeImportReq;
import com.finance.rule.request.PieceRangeListReq;
import com.finance.rule.request.PieceRangeReq;
import com.finance.rule.service.IPieceRangeService;
import com.finance.rule.service.ISettingLogService;
import com.finance.system.bean.pojo.RegionDetail;
import com.finance.system.bean.pojo.Supplier;
import com.finance.system.bean.pojo.User;
import com.finance.system.service.IRegionCodeService;
import com.finance.system.service.ISupplierService;
import com.finance.util.DateUtil;
import com.finance.util.export.ExportBuilder;
import com.finance.util.export.ExportFactory;
import com.finance.util.export.ImportUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 按件区间管理
 */
@Controller
@RequestMapping("/rule/piece")
public class PieceRangeController extends BaseController {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private IPieceRangeService pieceRangeService;

    @Resource
    private ISupplierService supplierService;

    @Resource
    private IRegionCodeService regionCodeService;

    @Resource
    private ISettingLogService settingLogService;

    private ObjectMapper objectMapper = new ObjectMapper();


    @RequestMapping("/index.htm")
    public String index() {
        return "rule/piece/index";
    }

    @RequestMapping(value = "/add.htm", method = RequestMethod.GET)
    public String add() {
        return "rule/piece/add";
    }

    @RequestMapping("/list")
    public Result list(PieceRangeListReq pieceRangeListReq) {
        Page page = Page.getInstance(pieceRangeListReq);
        PieceRangeList pieceRangeList = new PieceRangeList();
        PageResultBO<PieceRangeRule> resultBO;
        try {
            BeanUtils.copyProperties(pieceRangeList, pieceRangeListReq);
            page.setParams(pieceRangeList);
            resultBO = pieceRangeService.listByPage(page);
        } catch (Exception e) {
            this.logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN, "系统异常");
        }
        return getSuccessResult(resultBO);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Result add(@Valid PieceRangeReq form) throws BaseException {
        User authUser = getAuthUser();
        if (form == null) {
            throw new BaseException(BaseConstants.ERR_UNKOWN, "参数异常");
        }
        if (authUser == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        PieceRangeRule pieceRangeRule = new PieceRangeRule();
        pieceRangeRule.setSupplier(new Supplier());
        pieceRangeRule.getSupplier().setCode(form.getSupplierCode());
        pieceRangeRule.setRegionDetail(this.convertToRegion(form));
        try {
            BeanUtils.copyProperties(pieceRangeRule, form);
            pieceRangeRule.setCreateUid(authUser.getId());
            pieceRangeRule.setState(StateEnum.Valid.getState());
            pieceRangeService.add(pieceRangeRule);
        } catch (Exception e) {
            this.logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN, "添加失败");
        }

        return getSuccessResult("添加成功");
    }

    @RequestMapping(value = "/update.htm", method = RequestMethod.GET)
    public String update(String id, HttpServletRequest request) {
        PieceRangeRule pieceRange = null;
        try {
            pieceRange = this.pieceRangeService.getById(Long.parseLong(id));
        } catch (NumberFormatException e) {
            logger.info("【按件更新】查询异常{}", e.getMessage());
            logger.error(e.getMessage(), e);
        }
        if (pieceRange != null) {
            if (pieceRange.getStartTime() != null) {
                String startTime = DateUtil.dateFormat(pieceRange.getStartTime());
                request.setAttribute("startTime", startTime);
            }
            if (pieceRange.getEndTime() != null) {
                String endTime = DateUtil.dateFormat(pieceRange.getEndTime());
                request.setAttribute("endTime", endTime);
            }
        }
        request.setAttribute("pieceRange", pieceRange);
        return "rule/piece/update";
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public Result update(@Valid PieceRangeReq form, String id) {
        if (org.apache.commons.lang.StringUtils.isEmpty(id)) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        PieceRangeRule oldPieceRangeRule = pieceRangeService.getById(Long.parseLong(id));
        if (oldPieceRangeRule == null) {
            throw new BaseException(BaseConstants.ERR_NON_EXISTENT);
        }
        User user = getAuthUser();
        PieceRangeRule pieceRange = this.convertPieceRangeRule(form);
        String oldValue = null;
        try {
            oldValue = objectMapper.writeValueAsString(oldPieceRangeRule);
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(), e);
        }
        try {
            oldValue.length();
            pieceRange.setSnapshot(oldValue);
            pieceRange.setId(Long.parseLong(id));
            pieceRangeService.update(pieceRange);
        } catch (Exception e) {
            this.logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN, "更新失败");
        }
        settingLogService.addLog(user, OpearteEnum.UPDATE, TargetEnum.PIECE_RANGE_INFO, oldValue);
        return getSuccessResult("更新成功");
    }

    /**
     * 地区编码转化
     *
     * @param form
     * @return
     */
    private RegionDetail convertToRegion(PieceRangeReq form) {
        RegionDetail regionDetail = new RegionDetail();
        if (org.apache.commons.lang.StringUtils.isNotBlank(form.getCounty())) {
            regionDetail.setCode(form.getCounty());
            regionDetail.setCityCode(form.getCity());
            regionDetail.setProvinceCode(form.getProvince());
            regionDetail.setLevel(3);
            return regionDetail;
        } else if (StringUtils.isNotBlank(form.getCity())) {
            regionDetail.setCode(form.getCity());
            regionDetail.setProvinceCode(form.getProvince());
            regionDetail.setLevel(2);
            return regionDetail;
        } else if (StringUtils.isNotBlank(form.getProvince())) {
            regionDetail.setCode(form.getProvince());
            regionDetail.setLevel(1);
            return regionDetail;
        }
        return null;
    }
    private RegionDetail convertToRegion(PieceRangeImportReq form) {
        RegionDetail regionDetail = new RegionDetail();
        if (StringUtils.isNotBlank(form.getCounty())) {
            regionDetail.setCode(form.getCounty());
            regionDetail.setCityCode(form.getCity());
            regionDetail.setProvinceCode(form.getProvince());
            regionDetail.setLevel(3);
            return regionDetail;
        } else if (StringUtils.isNotBlank(form.getCity())) {
            regionDetail.setCode(form.getCity());
            regionDetail.setProvinceCode(form.getProvince());
            regionDetail.setLevel(2);
            return regionDetail;
        } else if (StringUtils.isNotBlank(form.getProvince())) {
            regionDetail.setCode(form.getProvince());
            regionDetail.setLevel(1);
            return regionDetail;
        }
        return null;
    }

    private PieceRangeRule convertPieceRangeRule(PieceRangeReq form) {
        User authUser = getAuthUser();
        if (authUser == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        PieceRangeRule pieceRangeRule = new PieceRangeRule();
        pieceRangeRule.setSupplier(new Supplier());
        pieceRangeRule.getSupplier().setCode(form.getSupplierCode());
        pieceRangeRule.setRegionDetail(this.convertToRegion(form));
        try {
            BeanUtils.copyProperties(pieceRangeRule, form);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        if (pieceRangeRule.getSettlementType() == null) {
            pieceRangeRule.setSettlementType(-1);
        }
        if (pieceRangeRule.getDirection() == null) {
            pieceRangeRule.setDirection(-1);
        }
        if (pieceRangeRule.getExpressScheduleType() == null) {
            pieceRangeRule.setExpressScheduleType(-1);
        }
        if (pieceRangeRule.getPackageSize() == null) {
            pieceRangeRule.setPackageSize(-1);
        }
        if (pieceRangeRule.getTemperature() == null) {
            pieceRangeRule.setTemperature(-1);
        }
        if (pieceRangeRule.getSigner() == null) {
            pieceRangeRule.setSigner(-1);
        }
        if (pieceRangeRule.getCod() == null) {
            pieceRangeRule.setCod(-1);
        }
        pieceRangeRule.setUpdateUid(authUser.getId());
        return pieceRangeRule;
    }
    private PieceRangeRule convertPieceRangeRule(PieceRangeImportReq form) {
        User authUser = getAuthUser();
        if (authUser == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        PieceRangeRule pieceRangeRule = new PieceRangeRule();
        pieceRangeRule.setSupplier(new Supplier());
        pieceRangeRule.getSupplier().setCode(form.getSupplierCode());
        pieceRangeRule.setRegionDetail(this.convertToRegion(form));
        try {
            BeanUtils.copyProperties(pieceRangeRule, form);
        } catch (Exception e) {
            throw new BaseException(BaseConstants.ERR_COPYBEAN);
        }
        if (pieceRangeRule.getSettlementType() == null) {
            pieceRangeRule.setSettlementType(-1);
        }
        if (pieceRangeRule.getDirection() == null) {
            pieceRangeRule.setDirection(-1);
        }
        if (pieceRangeRule.getExpressScheduleType() == null) {
            pieceRangeRule.setExpressScheduleType(-1);
        }
        if (pieceRangeRule.getPackageSize() == null) {
            pieceRangeRule.setPackageSize(-1);
        }
        if (pieceRangeRule.getTemperature() == null) {
            pieceRangeRule.setTemperature(-1);
        }
        if (pieceRangeRule.getSigner() == null) {
            pieceRangeRule.setSigner(-1);
        }
        if (pieceRangeRule.getCod() == null) {
            pieceRangeRule.setCod(-1);
        }
        pieceRangeRule.setUpdateUid(authUser.getId());
        return pieceRangeRule;
    }

    @RequestMapping("/delete")
    public Result delete(String ids) {
        User user = getAuthUser();
        if (StringUtils.isEmpty(ids)) {
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        if (user == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        List<String> list = Arrays.asList(ids.split(","));
        try {
            if (list.size() > 0) {
                boolean ret = this.pieceRangeService.delete(user.getId().toString(), list);
                if (!ret) {
                    return getSuccessResult(false);
                }
            }
        } catch (Exception e) {
            this.logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN, "删除失败");
        }
        return getSuccessResult("删除成功");
    }

    /**
     * 获取商家列表
     *
     * @return
     */
    @RequestMapping("/listsupplier")
    public Result listSupplier() {
        List<Supplier> suppliers = supplierService.listAll();
        return getSuccessResult(suppliers);
    }

    @RequestMapping("/listprovince")
    public Result listProvince() {
        List<Map> provinces = regionCodeService.getProvinces();
        return getSuccessResult(provinces);
    }

    /**
     * 导入Excel模板下载
     */
    @RequestMapping("/exporttemplate")
    public void export(HttpServletResponse response) {
        try {
            ExportBuilder builder = new ExportBuilder
                    (PieceParseBean.class,
                            new PieceParse()
                    );
            ExportFactory factory = ExportFactory.getExportFactory(
                    builder);
            factory.setDataList(new ArrayList<PieceRangeRule>()).outPut(response);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);

        }
    }


    /**
     * 导入结果下载
     */
    @RequestMapping("/down")
    public void importData(String fileKey, HttpServletResponse response) {
        FileUtils.downFile(fileKey, response);
    }

    /**
     * 导入
     */
    @RequestMapping("/import")
    public Result importData(@RequestParam("file") CommonsMultipartFile[] multipartFile) {
        InputStream in = null;
        List<PieceRangeRule> errList = null;
        List<String> errMsg = null;
        int successNums = 0;
        int totalNums = 0;
        try {
            User user = getAuthUser();
            in = multipartFile[0].getInputStream();
            List<PieceParseBean> list = ImportUtil.getImportFactory(in).outResult(PieceParseBean.class);
            errList = new ArrayList<PieceRangeRule>();
            errMsg = new ArrayList<String>();
            if (list != null && list.size() > 0) {
                for (PieceParseBean bean : list) {
                    PieceRangeImportReq form = new PieceRangeImportReq();
                    if (StringUtils.isNotBlank(bean.getSupplierCodeImport())) {
                        String supplierCode = supplierService.getCodeByName(bean.getSupplierCodeImport().trim());
                        if (StringUtils.isNotBlank(supplierCode)) {
                            form.setSupplierCode(supplierCode);
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getDirectionImport())) {
                        String direction = bean.getDirectionImport();
                        if ("配送".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.SEND.getValue()));
                        } else if ("上门换".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.CHANGE.getValue()));
                        } else if ("上门退".equals(direction)) {
                            form.setDirection(String.valueOf(DirectionEnum.BACK.getValue()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getSettlementTypeImport())) {
                        String settlementType = bean.getSettlementTypeImport().trim();
                        if ("自营".equals(settlementType)) {
                            form.setSettlementType(String.valueOf(SettlementTypeEnum.DELIVERY_MAN_PRICE.getValue()));
                        } else if ("合作站".equals(settlementType)) {
                            form.setSettlementType(String.valueOf(SettlementTypeEnum.COOPERATION_SITE_PRICE.getValue()));
                        } else if ("合作商".equals(settlementType)) {
                            form.setSettlementType(String.valueOf(SettlementTypeEnum.COOPERATION_BUSSINESS_PRICE));
                        } else if ("大型合作商".equals(settlementType)) {
                            form.setSettlementType(String.valueOf(SettlementTypeEnum.BIG_COOPERATION_BUSSINESS_PRICE.getValue()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getExpressScheduleTypeImport())) {
                        String expressScheduleType = bean.getExpressScheduleType();
                        if ("未知".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.unKnown.getValue()));
                        } else if ("当日达".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.today.getValue()));
                        } else if ("次晨达".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.nextMorning.getValue()));
                        } else if ("三日达".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.threeDay.getValue()));
                        } else if ("工作日".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.workDay.getValue()));
                        } else if ("节假日".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.holiday.getValue()));
                        } else if ("夜间配".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.night.getValue()));
                        } else if ("上午达".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.morning.getValue()));
                        } else if ("下午达".equals(expressScheduleType)) {
                            form.setExpressScheduleType(String.valueOf(ExpressScheduleTypeEnum.afternoon.getValue()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getTemperatureImport())) {
                        String temperature = bean.getTemperatureImport();
                        if ("常温".equals(temperature)) {
                            form.setTemperature(String.valueOf(TemperatureEnum.NORMAL.getValue()));
                        } else if ("生鲜冷链".equals(temperature)) {
                            form.setTemperature(String.valueOf(TemperatureEnum.FRESH_COLD.getValue()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getCodImport())) {
                        String cod = bean.getCodImport();
                        if ("否".equals(cod)) {
                            form.setCod(String.valueOf(CodEnum.Invalid.getState()));
                        } else if ("是".equals(cod)) {
                            form.setExpressScheduleType(String.valueOf(CodEnum.Valid.getState()));
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getSignerImport())) {
                        String signer = bean.getSignerImport();
                        if ("否".equals(signer)) {
                            form.setSigner("0");
                        } else if ("是".equals(signer)) {
                            form.setSigner("1");
                        }
                    }
                    if (StringUtils.isNotBlank(bean.getPackageSizeImport())) {
                        String packageSize = bean.getPackageSizeImport().trim();
                        if ("未知".equals(packageSize)) {
                            form.setSigner(String.valueOf(PackageSizeEnum.UNKNOWN.getValue()));
                        }else if ("小件".equals(packageSize)) {
                            form.setSigner(String.valueOf(PackageSizeEnum.SMALL.getValue()));
                        } else if ("中件".equals(packageSize)) {
                            form.setSigner(String.valueOf(PackageSizeEnum.MIDDLE.getValue()));
                        } else if ("大件".equals(packageSize)) {
                            form.setSigner(String.valueOf(PackageSizeEnum.BIG.getValue()));
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getProvinceImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getProvinceImport().trim());
                        if(StringUtils.isNotBlank(toProvince)){
                            form.setProvince(toProvince);
                        }
                    }

                    if(StringUtils.isNotBlank(bean.getProvinceImport())&&StringUtils.isNotBlank(bean.getCityImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getProvinceImport().trim());
                        String toCity = regionCodeService.getCodeByNameAndParent(bean.getCityImport().trim(),toProvince);
                        if(StringUtils.isNotBlank(toCity)){
                            form.setCity(toCity);
                            form.setCityError("true");
                        }
                    }
                    if(StringUtils.isNotBlank(bean.getProvinceImport())&&StringUtils.isNotBlank(bean.getCityImport())&&StringUtils.isNotBlank(bean.getProvinceImport())&&StringUtils.isNotBlank(bean.getCityImport())&&StringUtils.isNotBlank(bean.getCountyImport())){
                        String toProvince = regionCodeService.getCodeByName(bean.getProvinceImport().trim());
                        String toCity = regionCodeService.getCodeByNameAndParent(bean.getCityImport().trim(),toProvince);
                        String toCounty = regionCodeService.getCodeByNameAndParent(bean.getCountyImport().trim(),toCity);
                        if(StringUtils.isNotBlank(toCounty)){
                            form.setCounty(toCounty);
                            form.setCountryError("true");
                        }
                    }
                    form.setSecondPrice(bean.getSecondPrice());
                    form.setFirstPrice(bean.getFirstPrice());
                    form.setCityImport(bean.getCityImport());
                    form.setCountyImport(bean.getCountyImport());
                    form.setProvinceImport(bean.getProvinceImport());
                    form.setSignerImport(bean.getSignerImport());
                    form.setTemperatureImport(bean.getTemperatureImport());
                    form.setCodImport(bean.getCodImport());
                    form.setPackageSizeImport(bean.getPackageSizeImport());
                    form.setDirectionImport(bean.getDirectionImport());
                    form.setSettlementTypeImport(bean.getSettlementTypeImport());
                    List<String> msgList = validate(form);
                    PieceRangeRule pieceRangeRule= convertPieceRangeRule(form);
                    pieceRangeRule.setState(StateEnum.Valid.getState());
                    pieceRangeRule.setCreateUid(user.getId());
                    if (msgList == null || msgList.size() == 0) {
                        try {
                            pieceRangeService.add(pieceRangeRule);
                        } catch (BaseException e) {
                            errMsg.add(e.getErrorMsg());
                            errList.add(pieceRangeRule);
                        } catch (Exception e) {

                            errMsg.add(e.getMessage());
                            errList.add(pieceRangeRule);

                        }
                    } else {

                        StringBuffer msgStr = new StringBuffer();
                        for (String msg : msgList) {
                            msgStr.append(msg + "||");

                        }
                        msgStr.replace(msgStr.lastIndexOf("||"), msgStr.length(), "");
                        errMsg.add(msgStr.toString());
                        errList.add(pieceRangeRule);

                    }
                }
                successNums = list.size() - errList.size();
                totalNums = list.size();

            }
        } catch (Exception e)

        {
            return getFailResult(BaseConstants.ERR_UNKOWN, e.getMessage());
        } finally

        {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

        String fileKey = null;
        if (errList != null && errList.size() > 0)

        {
            String path = getRealPath("");
            File file = null;
            try {
                path += System.currentTimeMillis() + BaseConstants.DEFAULT_EXPORT_FILE_SUFFIX;
                file = new File(path);
                ExportBuilder builder = new ExportBuilder
                        (PieceRangeRule.class,
                                new PieceParse()
                        );
                ExportFactory factory = ExportFactory.getExportFactory(
                        builder);
                factory.setErrMsgList(errMsg).setDataList(errList).outPut(file);
                fileKey = FileUtils.uploadFile("import/piece/", file.getName(), file);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            } finally {
                if (file != null) {
                    file.delete();
                }
            }
        }

        Map<String, String> returnMap = new HashMap<String, String>();
        returnMap.put("fileKey", fileKey);
        returnMap.put("successNums", String.valueOf(successNums));
        returnMap.put("totalNums", String.valueOf(totalNums));
        return getSuccessResult(returnMap);
    }

}